-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement PartialOrd
and Ord
for Discriminant
#106418
base: master
Are you sure you want to change the base?
Conversation
(rustbot has picked a reviewer for you, use r? to override) |
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
@rustbot label +T-libs-api -T-libs |
Ord
for Discriminant
PartialOrd
and Ord
for Discriminant
Seems reasonable. @rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
Do we want to say anything about the ordering here being unstable? Does this imply that an enum that isn't itself implementing partialord now needs to worry about not reordering the variants? |
@Mark-Simulacrum I thought about that while reviewing this and felt like this part of the docs covered that aspect. But I think adding more clarifying docs to cover this explicitly would not hurt. |
Hm, I think that covers the standard library / compiler implementation, but I'm not sure it does much for library authors. That is, we can use a change in order to return different variants, but it doesn't necessarily mean that a library author defining an enum isn't now implicitly promising that they'll keep the same order. (since, in general, changing the enum definition would be a breaking change). To some extent the language is exposing a "new" way to learn about which order the variants are in here. |
@Mark-Simulacrum: The |
Related: #51561, which was an old issue proposing this. |
Right, but this is exposing that order on things that don't derive PartialOrd. If you're already exposing the order through PartialOrd, it's not a difference in behavior. |
@scottmcm seems to have felt similarly on that thread - #51561 (comment) - thanks for finding it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the ping here, Mark!
I remain strongly opposed to anything that makes it impossible for a library author to leave open the door to reorder their enum variants later.
If they want to opt-in to exposing the order, such as if these impls were impl<T> cmp::Ord for Discriminant<T> where T: ExposedVariantOrder
with a #[derive(ExposedVariantOrder)]
or something, then sure, having this would be fine.
But, for example, ControlFlow
is intentionally not exposing the order of its variants right now
rust/library/core/src/ops/control_flow.rs
Lines 82 to 83 in aa5dbee
// ControlFlow should not implement PartialOrd or Ord, per RFC 3058: | |
// https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#traits-for-controlflow |
and I'd like to keep it that way, but that's impossible if this PR lands. This is not just a PR for two impl
s, this is a PR for "no public enum can ever be reordered later".
(As another example here, there's been work in the past to see whether we could reorder the variants in Result
to make ?
more efficient, which would have to include manually writing the Ord
impl to match, but would be possible so long as this PR doesn't land, but if this does land, that becomes impossible.)
Even derive(PartialOrd)
I could at least change from deriving it to implementing it manually in order to continue to provide consistent behaviour after reordering, but there's no way to fixup a Discriminant
ordering later.
(Another direction that I'd like to see and would help the motivation here is better ways of accessing discriminants, like the derive
in rust-lang/rfcs#3046 )
#106418 (comment) makes sense to me, I actually always assumed that this comment already says that:
But it's actually not a 100% clear, but I would argue that this should be improved. "A discriminant of some variant will not change between compilations with the same compiler." implies that The main motivation of this PR is to allow implementers of rust/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs Lines 1098 to 1131 in aa5dbee
(used in PartialOrd /Ord as well, see sample output here)
So adding another trait, e.g. |
@rfcbot cancel |
@dtolnay proposal cancelled. |
It sounds like the position is that the discriminant order is public but not considered breaking without explicit documentation on the relevant type indicating it's stable? In other words, for a tool checking library semver (e.g. obi1kenobi/cargo-semver-checks#305) this PR is not intended to make it a breaking change for e.g. the standard library to reorder an enum that doesn't derive PartialOrd itself, and so the tool shouldn't return an error on such a change? That matches the transmute case and size_of, etc., so that would seem ok to me. |
Relaunching #106418 (comment) with libs-api + lang. @rfcbot fcp merge |
Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
@Mark-Simulacrum yes: it's in the same bucket as pub enum Enum {
Foo,
Bar,
} Even disregarding Or consider |
Is it important that the discriminant order remain the same between different versions of the compiler? If not I'd like to document that it could change, and left a suggestion to that effect. @rfcbot concern stability wrt compiler version Otherwise this proposal looks good to me. Thanks for pushing it through. @rfcbot reviewed |
The current proposal still specifies the So it should remain the same between compiler versions. |
The discriminant is guaranteed to be in the order in which variants are defined in the source code. This is necessary for many use cases such as using the discriminant ordering to implement |
The comparison with |
We discussed this in the lang meeting today without resolution. |
I remain concerned about exposing this with no opt-out on an unrestricted generic type I'm committing to making an alternative proposal because I shouldn't block without one. Please hold my feet to the fire if that's no up in a week. Basically, I have an idea for how we might be able to do this, from #106418 (comment)
Just to confirm, the primary use here is the
from the OP, right? (And similarly the derive-more cases from #106418 (comment) ) If there's anything else that people are wanting to use this for, please mention it. From a quick scan of other posts here, the only other thing brought up was #106418 (comment) which to me sounds like it wants a separate |
My comment was just a variation on it being difficult to implement |
@scottmcm friendly ping! |
Thanks for the poke, @daxpedda ! I've posted it as rust-lang/rfcs#3607 |
@rfcbot concern rfc-3607-instead |
Just wanted to quickly check my understanding of the stance w.r.t SemVer here: Does implementing The other ways of exposing a discriminant ( |
In my opinion inferring whether the discriminant values are promised to be stable from |
I found it difficult to implement
PartialOrd
orOrd
for enums without the ability to compare twoDiscriminant
values. Is it OK to implementPartialOrd
andOrd
forDiscriminant
?